﻿using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GanagroLiteData;
using Csla.Validation;
using GeneralUtilities;
using System.Data.Entity;


namespace GanagroLiteBO
{
    public class GLiteBO : IEditableObject, INotifyPropertyChanged, IDataErrorInfo, IBO
    {
      private bool m_Editing;
      private TiposOperacion _tipoOperacion = TiposOperacion.Otras;
      private bool _validationrulesSuspended = false;

        #region Properties
        private string _Codigo;
        public string CODIGO
        {
            get { return _Codigo; }
            set
            {
                if (_Codigo != value)
                {
                    _Codigo = value;
                    FirePropertyChangedNotification("CODIGO");
                    if (IsValid(false))
                    {
                        using (GlContext gContext = new GlContext())
                        {
                            Tatuaje = gContext.GANADOes.First(wp => wp.CODIGO == value).Tatuaje;
                        }
                    }
                }
            }
        }

        private string _Tatuaje;
        public string Tatuaje
        {
            get { return _Tatuaje; }
            set
            {
                if (_Tatuaje != value)
                {
                    _Tatuaje = value;
                    FirePropertyChangedNotification("Tatuaje");
                }
            }
        }

        public TiposOperacion TipoOperacion
        {
            get { return _tipoOperacion; }
            set
            {
                if (_tipoOperacion != value)
                {
                    _tipoOperacion = value;
                }
            }
        }

        #endregion

        #region Constructors

        public GLiteBO()
        {
            _tipoOperacion = TiposOperacion.Otras;
            AddBusinessRules();
        }

        public GLiteBO(string codigo)
        {
            AddBusinessRules();
            _tipoOperacion = TiposOperacion.Otras;
            this.CODIGO = codigo;
        }

        public GLiteBO(TiposOperacion tipoOperacion)
        {
            _tipoOperacion = tipoOperacion;
            AddBusinessRules();
        }

        public bool TienePesajes()
        {
            return UtilityDB.Exists("PESAJES",string.Format("CODIGO = '{0}'",this.CODIGO));
        }

        public List<string> GetUltimoPesoYFecha()
        {
            return UtilityDB.GetVals(string.Format("SELECT PESO,FECHA FROM UltimoPesajeCarne WHERE CODIGO = '{0}'", this.CODIGO));
        }

        public List<string> GetPrimerPesoYFecha()
        {
            return UtilityDB.GetVals(string.Format("SELECT PESO,FECHA FROM PrimerPesajeCarne WHERE CODIGO = '{0}'", this.CODIGO));
        }

        public List<string> PesajePrevioYFecha(DateTime fecha)
        {
            return UtilityDB.GetVals(
                string.Format("SELECT PESO,FECHA FROM Pesajes WHERE FECHA = (SELECT MAX(FECHA) FROM Pesajes WHERE FECHA < '{0}' AND CODIGO ='{1}'", fecha,this.CODIGO));
        }

        #endregion

        #region Methods
        public void Guardar()
        {
            if (IsValid())
            {
                using (GlContext glContext = new GlContext())
                {

                    GANADO GanadoDO = glContext.GANADOes.FirstOrDefault(wp => wp.CODIGO == this.CODIGO);
                    glContext.GANADOes.Attach(GanadoDO);
                    GanadoDO.Tatuaje = this.Tatuaje;
                    glContext.Entry(GanadoDO).State = EntityState.Modified; //TODO: test this
                    glContext.SaveChanges();
                }
            }
        }


        public BindingList<string> ListaPesajes()
        {
            using (GlContext glContext = new GlContext())
            {
                GANADO currentGanadoDO = glContext.GANADOes.FirstOrDefault(q => q.CODIGO == _Codigo);

                BindingList<string> listaPesajes = new BindingList<string>();

                if (currentGanadoDO != null)
                {
                    var pesajes = currentGanadoDO.PESAJES
                                   .OrderBy(wp => wp.Fecha)
                                   .Select(r => string.Format("{0} : {1}\r\n", r.Fecha.ToShortDateString(), r.Peso.ToString()))
                                   .ToList<string>();

                    listaPesajes = new BindingList<string>(pesajes);
                }

            return listaPesajes;
            }
        }

        #endregion Methods

        #region Validaciones

        private ValidationRules _validationRules;
        public ValidationRules ValidationRules
        {
            get
            {
                if (_validationRules == null)
                    _validationRules = new ValidationRules(this);
                return _validationRules;
            }
        }

        public bool IsValid()
        {
            return IsValid(_validationrulesSuspended);
        }

        public bool IsValid(bool BypassValidation)
        {
            if (BypassValidation == false)
            {
                ValidationRules.CheckRules();
            }

            return ValidationRules.GetBrokenRules().ErrorCount == 0;
        }

        private static bool CodigoEsValido<T>(T target, Csla.Validation.RuleArgs e) where T : GLiteBO
        {
            string message = string.Empty;
            bool success = true;

            if (utilities.CodigoEsValido(target.CODIGO, ref message, target.TipoOperacion) == false)
            {
                e.Description = message;
                success = false;            }

            return success;
        }

        private void AddBusinessRules()
        {
            try
            {
                // ValidationRules.AddRule(new Csla.Validation.RuleHandler<GanagroLiteBOTemplate,RuleArgs>(), "Fecha");
                //public static bool CodigoEsValido
                ValidationRules.AddRule(new Csla.Validation.RuleHandler<GLiteBO, RuleArgs>(CodigoEsValido), "Codigo");

            }
            catch (Exception ex)
            {
                throw (new Exception("AddBusinessRules: " + ex.Message, ex));
            }

        }

        #endregion

        #region INotifyPropertyChanged Implementation
        protected void FirePropertyChangedNotification(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
            ValidationRules.CheckRules(propName);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region IDataErrorInfo Members


        [Browsable(false)]
        public string Error
        {
            get
            {
                if (!ValidationRules.IsValid)
                {
                    return ValidationRules.GetBrokenRules().First().Description;
                }
                else
                { return String.Empty; }
            }
        }

        [Browsable(false)]
        public string this[string columnName]
        {
            get
            {
                string result = string.Empty;
                if (!ValidationRules.IsValid)
                {
                    BrokenRule rule = ValidationRules.GetBrokenRules().GetFirstBrokenRule(columnName);
                    if (rule != null)
                        result = rule.Description;
                }

                return result;
            }
        }
        #endregion

        #region IEditableObject Members

        public void BeginEdit()
        {
            m_Editing = true;
        }

        public void CancelEdit()
        {
            m_Editing = false;
        }

        public void EndEdit()
        {
            //if (m_Editing)
            //{
            //}

            m_Editing = false;
        }

        #endregion

    }

    public class Tatuajes : BindingListView<GLiteBO> { }

}
